home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C
/
Frameworks
/
Grant's CGI Framework 1.0b14
/
Util
/
main.c
< prev
next >
Wrap
Text File
|
1996-04-11
|
8KB
|
332 lines
/*****
*
* Grant's CGI Shell (Common Grant Interface :-)
* http://arpp.carleton.ca/grant/mac/grantscgi/
*
* main.c
*
* by Grant Neufeld
*
* Copyright ©1995,1996 by Grant Neufeld
*
* http://arpp.carleton.ca/grant/
* gneufeld@ccs.carleton.ca
* grant@acm.org
*
* This source may be freely used as long as the copyright notice is kept in the source.
* I ask that you let me know of any enhancements (read: bug fixes) to this code.
* I would also like copies of (or discounts on) anything you produce using this code, please.
*
*****/
#define __MainSegment__ 1
#include "MyConfiguration.h"
#include <string.h>
#include <Threads.h>
//#if __profile__ && __MWERKS__
//#include <Profiler.h>
//#endif
#include "compiler_stuff.h"
#include "constants.h"
#include "globals.h"
#include "DebugUtil.h"
#include "ErrorUtil.h"
#include "EventUtil.h"
#include "MemoryUtil.h"
#include "MenuFunc.h"
#include "ProcessUtil.h"
#include "Quit.h"
#include "Startup.h"
/*** LOCAL VARIABLES ***/
static RgnHandle vTheMouseRgn;
/*** LOCAL PROTOTYPES ***/
static void mainEventLoop ( void );
static void startupToolbox ( void );
static Boolean initAppMemory ( void );
static OSErr initStackGrow ( Size );
/*** FUNCTIONS ***/
/* Application entry point. */
void
main ( void )
{
/* Application is not set to quit */
gQuit = false;
/* Included here because of InitWindows() allocation of non-relocatable blocks.
This needs to be done before any other code segments are loaded.
IM:Processes 7-5 */
/* initialize standard toolbox managers */
startupToolbox ();
/* Included here because of MoreMasters() allocation of non-relocatable blocks.
This needs to be done before any other code segments are loaded.
IM:Processes 7-5 */
if ( !(initAppMemory()) )
{
/* inform user of insufficient memory */
ErrorStartup ( kerrStartupMemory );
ExitToShell ();
}
//•moved to CGI.c
// #if __profile__ && __MWERKS__
// gProfileOn = !( ProfilerInit ( collectDetailed, bestTimeBase, 20, 5 ) );
// #endif
/* do all the needed application setup */
StartupApplication ();
/* main loop for handling system and user events */
mainEventLoop ();
// #if __profile__ && __MWERKS__
// if ( gProfileOn )
// {
// ProfilerDump("\p" kProfileNameStr "-" kProcessorString ".prof");
// ProfilerTerm();
// }
// #endif
ExitToShell ();
} /* main */
/* main loop for handling system and user events.
Continuously loop until application is set to quit. */
static void
mainEventLoop ( void )
{
#if !(kCompileWithQuitOnLowMemory)
OSErr theErr;
#endif
Boolean eventResult;
EventRecord event;
short loopCounter;
while ( !gQuit )
{
#if !(kCompileWithQuitOnLowMemory)
/* if app doesn't quit on low memory, may need to recover emergency mem */
/* IM-Memory: 1-48 */
if ( !(IsEmergencyMemAvail()) )
{
theErr = RecoverEmergencyMemory ();
if ( theErr != noErr )
{
gQuit = true;
}
}
#endif
#if kCompileWithThreadsOptional
if ( gHasThreadMgr )
{
#endif
/* Yield more often if there are any sub-threads. The 'more often'
depends on how many sub-threads there are */
if ( gThreadTotal > 1 )
{
for ( loopCounter = nil; loopCounter < gThreadTotal; loopCounter++ )
{
ThreadYield ( nil, false );
}
}
else
{
/* just yield once if there are no sub-threads, or only one */
ThreadYield ( nil, false );
}
#if kCompileWithThreadsOptional
}
#endif
if ( !gQuit )
{
/* wait until the next event */
eventResult = WaitNextEvent ( everyEvent, &event, gSleepTicks, nil );
if ( eventResult != nil )
{
/* there is an event */
/* figure out which event and process it */
switch ( event.what )
{
case kHighLevelEvent:
doHighLevelEvent ( &event );
break;
#if kCompileWithForeground
/* these are interface events, only applicable if this is a
forground application. Faceless background applications
will not receive these events */
case mouseDown:
doMouseDown ( &event );
break;
case mouseUp:
doMouseUp ( &event );
break;
case keyDown:
doKeyDown ( &event );
break;
case autoKey:
doAutoKey ( &event );
break;
/* typically not sent to the application. IM-MTE: 2-28 */
case keyUp:
doKeyUp ( &event );
break;
case activateEvt:
doActivateEvent ( &event );
break;
case updateEvt:
doUpdateEvent ( &event );
break;
/* suspend or resume */
case osEvt:
doOsEvt ( &event );
break;
/* disk inserted */
case diskEvt:
doDiskEvt ( &event );
break;
#endif /* kCompileWithForeground */
default:
doIdle ( &event );
break;
}
}
else
{
/* no event */
doIdle ( &event );
}
}
if ( gQuit )
{
/* the quit flag has been set, prepare to quit. If the quit
preparation fails, the flag will be reset and we'll continue
with the event loop. */
QuitPrepare ( true );
}
}
} /* mainEventLoop */
/*** INITIALIZATION ***/
#pragma mark -
/* initialize standard toolbox managers */
static void
startupToolbox ( void )
{
InitGraf ( (Ptr)(&qd.thePort) ); /* InitGraf must be first */
#if kCompileWithForeground
/* initialize interface managers */
InitFonts ();
InitWindows ();
InitMenus (); /* InitMenus must be after InitWindows */
FlushEvents ( everyEvent, nil ); /* IM-MTE: 2-93 */
TEInit ();
InitDialogs ( nil ); /* InitDialogs must be after TEInit */
InitCursor ();
#endif
} /* startupToolbox */
/* Return true if memory initialization was successful. */
static Boolean
initAppMemory ( void )
{
short mstrPtrsAllocated;
long freeMemAvail;
Boolean success;
Handle sacrificeHandle;
#if !(kCompileWithForeground)
/* Background only apps get a default 8K stack instead of 24K.
Increase stack size if set to background only - just to be on the safe side */
success = ( initStackGrow(16384) == noErr );
#endif
/* NOTE: MaxApplZone must be called before any memory is allocated by threads
other than the main (application) thread. */
/* maximize available memory in the application heap */
MaxApplZone ();
freeMemAvail = FreeMem ();
if ( freeMemAvail < kMinSegSize )
{
/* not enough memory for application to run */
success = false;
}
else
{
/* to avoid memory fragmentation, allocate master pointers at bottom of heap */
for ( mstrPtrsAllocated = 0; mstrPtrsAllocated < kMoreMasterCalls; mstrPtrsAllocated++ )
{
MoreMasters ();
}
success = InitializeEmergencyMemory ( nil );
}
/* Allocate a 1K memory block, force it to the top of the heap, and lock it.
This block is not used for anything - it is put at the top of the heap
as a sacrifice because sometimes MacSLIP's VBL task trashes the end of
the heap.
from "NewsWatcher" 'newswatcher.c' */
sacrificeHandle = MemoryNewHandle ( 1024, nil );
if ( sacrificeHandle != nil )
{
HLockHi ( sacrificeHandle );
}
return success;
} /* initAppMemory */
/* */
static OSErr
initStackGrow ( Size increaseSize )
{
OSErr theErr;
my_assert ( (increaseSize % 1024) == nil, "\pinitStackGrow: size is not multiple of 1024" );
/* Increase the stack size by lowering the heap limit. */
SetApplLimit ( (Ptr)(((unsigned long)GetApplLimit()) - increaseSize) );
theErr = MemError ();
return theErr;
} /* initStackGrow */
/*** EOF ***/